﻿/**
 * \brief TCP连接任务池实现
 * \file CTcpTaskPool.cc
 */

#include "CTcpTaskPool.h"
#include "CThreadPattern.h"
#include "CVerifyThread.h"
#include "CRunningThread.h"
#include "Log.h"

/**
 * \brief 构造函数
 * \param _maxVerifyThreadNum：验证线程最大数量
 * \param _maxRunningThreadNum：处理线程最大数量
 */
CTcpTaskPool::CTcpTaskPool(size_t _maxVerifyThreadNum, size_t _maxRunningThreadNum)
	: _M_maxVerifyThreadNum(_maxVerifyThreadNum), _M_maxRunningThreadNum(_maxRunningThreadNum)
{
	this->_M_pSyncThread = NULL;
	this->_M_pRecycleThread = NULL;
}

/**
 * \brief 析构函数
 */
CTcpTaskPool::~CTcpTaskPool()
{}

/**
 * \brief 初始化
 */
bool CTcpTaskPool::init()
{
	this->_M_pSyncThread = new CThreadPattern<CSyncThread>(this);
	if(!this->_M_pSyncThread)
	{
		log::_ERROR_LOG("[TCP连接任务池]同步线程分配内存失败，%s", __PRETTY_FUNCTION__);
		return false;
	}

	this->_M_pRecycleThread = new CThreadPattern<CRecycleThread>(this);
	if(!this->_M_pRecycleThread)
	{
		log::_ERROR_LOG("[TCP连接任务池]回收线程分配内存失败，%s", __PRETTY_FUNCTION__);
		return false;
	}

	size_t pos = 0;
	for(; pos < this->_M_maxVerifyThreadNum; ++pos)
	{
		CThreadPattern<CVerifyThread>* pThread = new CThreadPattern<CVerifyThread>(this);
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]验证线程分配内存失败，%s", __PRETTY_FUNCTION__);
			return false;
		}

		if(!this->_M_verifyThreads.addThread(pThread))
                {                     
                        log::_ERROR_LOG("[TCP连接任务池]加入验证线程组失败，%s", __PRETTY_FUNCTION__);
                        return false; 
                } 
	}

	pos = 0;
	for(; pos < this->_M_maxRunningThreadNum; ++pos)
	{
		CThreadPattern<CRunningThread>* pThread = new CThreadPattern<CRunningThread>(this);
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]处理线程分配内存失败，%s", __PRETTY_FUNCTION__);
			return false;
		}

		if(!this->_M_runningThreads.addThread(pThread))
		{                     
			log::_ERROR_LOG("[TCP连接任务池]加入处理线程组失败，%s", __PRETTY_FUNCTION__);
			return false; 
		} 
	}

	return true;
}

/**
 * \brief 开启
 */
bool CTcpTaskPool::start()
{
	/// 验证线程
	size_t pos = 0;
	for(; pos < this->_M_maxVerifyThreadNum; ++pos)
	{
		CThread* pThread = this->_M_verifyThreads.getByIdx(pos);
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]验证线程(%u)为空，%s", pos, __PRETTY_FUNCTION__);
			return false;
		}

		if(!pThread->start())
		{
			log::_ERROR_LOG("[TCP连接任务池]验证线程(%u)启动失败", pos);
			return false;
		}
	}

	/// 同步线程
	if(!this->_M_pSyncThread->start())
	{
		log::_ERROR_LOG("[TCP连接任务池]同步线程启动失败");
		return false;
	}

	/// 处理线程
	pos = 0;
	for(; pos < this->_M_maxRunningThreadNum; ++pos)
	{
		CThread* pThread = this->_M_runningThreads.getByIdx(pos);
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]处理线程(%u)为空，%s", pos, __PRETTY_FUNCTION__);
			return false;
		}

		if(pThread->start())
		{
			log::_ERROR_LOG("[TCP连接任务池]处理线程(%u)启动失败", pos);
			return false;
		}
	}

	/// 回收线程
	if(this->_M_pRecycleThread->start())
	{
		log::_ERROR_LOG("[TCP连接任务池]回收线程启动失败");
		return false;
	}

	return true;
}

/**
 * \brief 加入验证线程
 * \param _pTask：线程指针
 */
bool CTcpTaskPool::addVerify(CTcpTask* _pTask)
{
	if(_pTask)
	{
		static unsigned int verifyHash = 0;
		CThreadPattern<CVerifyThread>* pThread = static_cast<CThreadPattern<CVerifyThread>*>(this->_M_verifyThreads.getByIdx(verifyHash++ % this->_M_maxVerifyThreadNum));
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]无法获得验证线程，%s", __PRETTY_FUNCTION__);
			return false;
		}

		pThread->add(_pTask);

		return true;
	}

	return false;
}

/**
 * \brief 加入同步线程
 * \param _pTask：线程指针
 */
bool CTcpTaskPool::addSync(CTcpTask* _pTask)
{
	if(_pTask)
	{
		if(!this->_M_pSyncThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]无法获得同步线程，%s", __PRETTY_FUNCTION__);
			return false;
		}

		this->_M_pSyncThread->add(_pTask);

		return true;
	}

	return false;
}

/**
 * \brief 加入处理线程
 * \param _pTask：线程指针
 */
bool CTcpTaskPool::addRunning(CTcpTask* _pTask)
{
	if(_pTask)
	{
		static unsigned int runningHash = 0;
		CThreadPattern<CRunningThread>* pThread = static_cast<CThreadPattern<CRunningThread>*>(this->_M_runningThreads.getByIdx(runningHash++ % this->_M_maxRunningThreadNum));
		if(!pThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]无法获得处理线程，%s", __PRETTY_FUNCTION__);
			return false;
		}

		pThread->add(_pTask);

		return true;
	}

	return false;
}

/**
 * \brief 加入回收线程
 * \param _pTask：线程指针
 */
bool CTcpTaskPool::addRecycle(CTcpTask* _pTask)
{
	if(_pTask)
	{
		if(!this->_M_pRecycleThread)
		{
			log::_ERROR_LOG("[TCP连接任务池]无法获得回收线程，%s", __PRETTY_FUNCTION__);
			return false;
		}

		this->_M_pRecycleThread->add(_pTask);

		return true;
	}

	return false;
}

